home *** CD-ROM | disk | FTP | other *** search
/ Adobe Graphics & Publishing SDK 1996 December / Adobe Graphics & Publishing SDK 1996 December.iso / pc / ps40sdk / examples / format / simpleformat / common / simpleformat.c next >
Encoding:
C/C++ Source or Header  |  1996-10-22  |  16.4 KB  |  834 lines

  1. /*
  2.     File: SimpleFormat.c
  3.  
  4.     Copyright (c) 1993-6, Adobe Systems Incorporated.
  5.     All rights reserved.
  6.     
  7.     Example file format module.
  8. */
  9.  
  10. #if __MWERKS__
  11. #include <SetupA4.h> // A4-globals
  12. #include <A4Stuff.h> // A4-globals
  13. #endif
  14.  
  15. #if defined(THINK_C) || defined(__MWERKS__)
  16. #define ENTRYPOINT main
  17. #endif
  18.  
  19. #include "SimpleFormat.h"
  20.  
  21. Handle hDllInstance = NULL;
  22.  
  23. /*****************************************************************************/
  24.  
  25. void InitGlobals (GPtr globals);
  26. void DoReadPrepare (GPtr globals);
  27. void DoReadStart (GPtr globals);
  28. void DoReadContinue (GPtr globals);
  29. void DoReadFinish (GPtr globals);
  30. void DoOptionsPrepare (GPtr globals);
  31. void DoOptionsStart (GPtr globals);
  32. void DoOptionsContinue (GPtr globals);
  33. void DoOptionsFinish (GPtr globals);
  34. void DoEstimatePrepare (GPtr globals);
  35. void DoEstimateStart (GPtr globals);
  36. void DoEstimateContinue (GPtr globals);
  37. void DoEstimateFinish (GPtr globals);
  38. void DoWritePrepare (GPtr globals);
  39. void DoWriteStart (GPtr globals);
  40. void DoWriteContinue (GPtr globals);
  41. void DoWriteFinish (GPtr globals);
  42. void DoFilterFile (GPtr globals);
  43. static Boolean TestAndStoreResult (GPtr globals, OSErr result);
  44. static Boolean TestAndStoreCancel (GPtr globals, Boolean tocancel);
  45. static Boolean CheckIdentifier (char identifier []);
  46. static void SetIdentifier (char identifier []);
  47. static Boolean CheckForServices (GPtr globals);
  48. static int32 RowBytes (GPtr globals);
  49. static Boolean AllocatePixelBuffer (GPtr globals);
  50. static void DisposePixelBuffer (GPtr globals);
  51. static void ReadSome (GPtr globals, int32 count, void *buffer);
  52. static void WriteSome (GPtr globals, int32 count, void *buffer);
  53. static void ReadRow (GPtr globals);
  54. static void WriteRow (GPtr globals);
  55. static void DisposeImageResources (GPtr globals);
  56.  
  57. /*****************************************************************************/
  58.  
  59. /* Main dispatching routine.  Initializes and sets up the global variables,
  60.    and performs the operation specified by the selector. */
  61.  
  62. #if MSWindows
  63.        void ENTRYPOINT (short selector,
  64.                         FormatRecordPtr formatParamBlock,
  65.                         long *data,
  66.                         short *result)
  67. #else
  68. pascal void ENTRYPOINT (short selector,
  69.                         FormatRecordPtr formatParamBlock,
  70.                         long *data,
  71.                         short *result)
  72. #endif
  73.     {
  74.  
  75.     /* Set up the globals. */
  76.  
  77.     Globals globalValues;
  78.     GPtr globals = &globalValues;
  79.     
  80.     #if __MWERKS__
  81.     EnterCodeResource(); // A4-globals
  82.     #endif
  83.     
  84.     if (!*data)
  85.         {
  86.         
  87.         InitGlobals (globals);
  88.  
  89.         *data = (long) NewHandle (sizeof (Globals));
  90.         
  91.         if (!*data)
  92.             {
  93.             *result = memFullErr;
  94.             return;
  95.             }
  96.             
  97.         ** (GHdl) *data = globalValues;
  98.         
  99.         }
  100.         
  101.     globalValues = ** (GHdl) *data;
  102.     
  103.     /* Perform the requested operation */
  104.  
  105.     gStuff  = formatParamBlock;
  106.     gResult = noErr;
  107.  
  108.     switch (selector)
  109.         {
  110.  
  111.         case formatSelectorAbout:
  112.             DoAbout (globals);
  113.             break;
  114.  
  115.         case formatSelectorReadPrepare:
  116.             DoReadPrepare (globals);
  117.             break;
  118.  
  119.         case formatSelectorReadStart:
  120.             DoReadStart (globals);
  121.             break;
  122.  
  123.         case formatSelectorReadContinue:
  124.             DoReadContinue (globals);
  125.             break;
  126.  
  127.         case formatSelectorReadFinish:
  128.             DoReadFinish (globals);
  129.             break;
  130.  
  131.         case formatSelectorOptionsPrepare:
  132.             DoOptionsPrepare (globals);
  133.             break;
  134.  
  135.         case formatSelectorOptionsStart:
  136.             DoOptionsStart (globals);
  137.             break;
  138.  
  139.         case formatSelectorOptionsContinue:
  140.             DoOptionsContinue (globals);
  141.             break;
  142.  
  143.         case formatSelectorOptionsFinish:
  144.             DoOptionsFinish (globals);
  145.             break;
  146.  
  147.         case formatSelectorEstimatePrepare:
  148.             DoEstimatePrepare (globals);
  149.             break;
  150.  
  151.         case formatSelectorEstimateStart:
  152.             DoEstimateStart (globals);
  153.             break;
  154.  
  155.         case formatSelectorEstimateContinue:
  156.             DoEstimateContinue (globals);
  157.             break;
  158.  
  159.         case formatSelectorEstimateFinish:
  160.             DoEstimateFinish (globals);
  161.             break;
  162.  
  163.         case formatSelectorWritePrepare:
  164.             DoWritePrepare (globals);
  165.             break;
  166.  
  167.         case formatSelectorWriteStart:
  168.             DoWriteStart (globals);
  169.             break;
  170.  
  171.         case formatSelectorWriteContinue:
  172.             DoWriteContinue (globals);
  173.             break;
  174.  
  175.         case formatSelectorWriteFinish:
  176.             DoWriteFinish (globals);
  177.             break;
  178.             
  179.         case formatSelectorFilterFile:
  180.             DoFilterFile (globals);
  181.             break;
  182.  
  183.         default:
  184.             gResult = formatBadParameters;
  185.         }
  186.  
  187.     *result = gResult;
  188.     ** (GHdl) *data = globalValues;
  189.     
  190.     #if __MWERKS__
  191.     ExitCodeResource(); // A4-globals
  192.     #endif
  193.         
  194.     }
  195.  
  196. /*****************************************************************************/
  197.  
  198. /* Sets the global variables to their default values. */
  199.  
  200. void InitGlobals (GPtr globals)
  201.     {
  202.  
  203.     Ptr        p;
  204.     int16    count;
  205.     
  206.     p = (Ptr) globals;
  207.     count = sizeof(Globals);
  208.     
  209.     while (count--)
  210.         *p++ = 0;
  211.  
  212.     }
  213.  
  214. /*****************************************************************************/
  215.  
  216. static Boolean CheckIdentifier (char identifier [])
  217.     {
  218.     
  219.     return identifier[0] == 'o' &&
  220.            identifier[1] == 'n' &&
  221.            identifier[2] == 'e' &&
  222.            identifier[3] == 'b' &&
  223.            identifier[4] == 'r' &&
  224.            identifier[5] == 'a' &&
  225.            identifier[6] == 'i' &&
  226.            identifier[7] == 'n';
  227.     
  228.     }
  229.  
  230. /*****************************************************************************/
  231.  
  232. static void SetIdentifier (char identifier [])
  233.     {
  234.     
  235.     identifier[0] = 'o';
  236.     identifier[1] = 'n';
  237.     identifier[2] = 'e';
  238.     identifier[3] = 'b';
  239.     identifier[4] = 'r';
  240.     identifier[5] = 'a';
  241.     identifier[6] = 'i';
  242.     identifier[7] = 'n';
  243.     
  244.     }
  245.  
  246. /*****************************************************************************/
  247.  
  248. static Boolean CheckForServices (GPtr globals)
  249.     {
  250.     
  251.     return WarnBufferProcsAvailable () &&
  252.            WarnAdvanceStateAvailable () &&
  253.            WarnHandleProcsAvailable ();
  254.     
  255.     }
  256.  
  257. /*****************************************************************************/
  258.  
  259. static Boolean TestAndStoreResult (GPtr globals, OSErr result)
  260.     {
  261.     
  262.     if (result != noErr)
  263.         {
  264.         if (gResult == noErr)
  265.             gResult = result;
  266.         return FALSE;
  267.         }
  268.     else
  269.         return TRUE;
  270.     
  271.     }
  272.     
  273. #define TSR(x) TestAndStoreResult (globals, x)
  274.  
  275. /*****************************************************************************/
  276.  
  277. static Boolean TestAndStoreCancel (GPtr globals, Boolean tocancel)
  278.     {
  279.     
  280.     if (tocancel)
  281.         {
  282.         if (gResult == noErr)
  283.             gResult = userCanceledErr;
  284.         return FALSE;
  285.         }
  286.     else
  287.         return TRUE;
  288.     
  289.     }
  290.     
  291. #define TSC(x) TestAndStoreCancel (globals, x)
  292.  
  293. /*****************************************************************************/
  294.  
  295. static int32 RowBytes (GPtr globals)
  296.     {
  297.     
  298.     return (gStuff->imageSize.h * (int32) gStuff->depth + 7) >> 3;
  299.     
  300.     }
  301.  
  302. /*****************************************************************************/
  303.  
  304. static Boolean AllocatePixelBuffer (GPtr globals)
  305.     {
  306.     
  307.     BufferID buffer;
  308.     
  309.     if (gResult != noErr) return FALSE;
  310.  
  311.     /* We will want a buffer that is one line wide. */
  312.     
  313.     gPixelBuffer = 0;
  314.     
  315.     gRowBytes = RowBytes (globals);
  316.     
  317.     if (!TSR (AllocateBuffer (gRowBytes, &buffer))) return FALSE;
  318.     
  319.     gPixelBuffer = buffer;
  320.     
  321.     gPixelData = LockBuffer (gPixelBuffer, FALSE);
  322.     
  323.     return TRUE;
  324.     
  325.     }
  326.  
  327. /*****************************************************************************/
  328.  
  329. static void DisposePixelBuffer (GPtr globals)
  330.     {
  331.     
  332.     if (gPixelBuffer != 0)
  333.         {
  334.         
  335.         FreeBuffer (gPixelBuffer);
  336.         
  337.         gPixelBuffer = 0;
  338.         gPixelData = 0;
  339.         
  340.         }
  341.     
  342.     }
  343.  
  344. /*****************************************************************************/
  345.  
  346. void DoReadPrepare (GPtr globals)
  347.     {
  348.     
  349.     gStuff->maxData = 0;
  350.     
  351.     }
  352.  
  353. /*****************************************************************************/
  354.  
  355. static void ReadSome (GPtr globals, int32 count, void *buffer)
  356.     {
  357.     
  358.     int32 readCount = count;
  359.     
  360.     if (gResult != noErr)
  361.         return;
  362.     
  363.     gResult = FSRead (gStuff->dataFork, &readCount, buffer);
  364.     
  365.     if (gResult == noErr && readCount != count)
  366.         gResult = eofErr;
  367.     
  368.     }
  369.  
  370. /*****************************************************************************/
  371.  
  372. static void WriteSome (GPtr globals, int32 count, void *buffer)
  373.     {
  374.     
  375.     int32 writeCount = count;
  376.     
  377.     if (gResult != noErr)
  378.         return;
  379.     
  380.     gResult = FSWrite (gStuff->dataFork, &writeCount, buffer);
  381.     
  382.     if (gResult == noErr && writeCount != count)
  383.         gResult = dskFulErr;
  384.     
  385.     }
  386.  
  387. /*****************************************************************************/
  388.  
  389. static void ReadRow (GPtr globals)
  390.     {
  391.     
  392.     ReadSome (globals, gRowBytes, gPixelData);
  393.     
  394.     }
  395.  
  396. /*****************************************************************************/
  397.  
  398. static void WriteRow (GPtr globals)
  399.     {
  400.     
  401.     WriteSome (globals, gRowBytes, gPixelData);
  402.     
  403.     }
  404.  
  405. /*****************************************************************************/
  406.  
  407. static void DisposeImageResources (GPtr globals)
  408.     {
  409.     
  410.     if (gStuff->imageRsrcData)
  411.         {
  412.         
  413.         PIDisposeHandle (gStuff->imageRsrcData);
  414.         
  415.         gStuff->imageRsrcData = NULL;
  416.         
  417.         gStuff->imageRsrcSize = 0;
  418.         
  419.         }
  420.     
  421.     }
  422.  
  423. /*****************************************************************************/
  424.  
  425. void DoReadStart (GPtr globals)
  426.     {
  427.     
  428.     FileHeader header;
  429.     Boolean    servicesAvailable = false;
  430.     
  431.     ReadScriptParamsOnRead (globals); // override params here
  432.     
  433.     /* Exit if we have already encountered an error. */
  434.  
  435.     if (gResult != noErr) return;
  436.         
  437.     /* Check for the needed services. */
  438.     
  439.     if (!TSC ((Boolean)(!CheckForServices(globals))) ) return;
  440.  
  441.     /* If we have not encountered an error, then we want to read
  442.        the file header. */
  443.        
  444.     if (!TSR (SetFPos (gStuff->dataFork, fsFromStart, 0))) return;
  445.     
  446.     ReadSome (globals, sizeof (FileHeader), &header);
  447.     
  448.     if (gResult != noErr) return;
  449.     
  450.     if (!CheckIdentifier (header.identifier))
  451.         {
  452.         gResult = formatCannotRead;
  453.         return;
  454.         }
  455.     
  456.     gStuff->imageMode = header.mode;
  457.     gStuff->imageSize.v = header.rows;
  458.     gStuff->imageSize.h = header.cols;
  459.     gStuff->depth = header.depth;
  460.     gStuff->planes = header.planes;
  461.     
  462.     /* Next, we will try to read the image resources. */
  463.     
  464.     if (header.resourceLength > 0)
  465.         {
  466.         
  467.         gStuff->imageRsrcData = PINewHandle (header.resourceLength);
  468.         
  469.         if (!gStuff->imageRsrcData)
  470.             {
  471.             gResult = memFullErr;
  472.             return;
  473.             }
  474.             
  475.         ReadSome (globals,
  476.                   header.resourceLength,
  477.                   PILockHandle (gStuff->imageRsrcData, FALSE));
  478.         
  479.         PIUnlockHandle (gStuff->imageRsrcData);
  480.         
  481.         if (gResult != noErr)
  482.             goto CleanUp;
  483.             
  484.         gStuff->imageRsrcSize = header.resourceLength;
  485.         
  486.         }
  487.         
  488.     /* Next, we will will read the lookup tables if in indexed color mode. */
  489.     
  490.     if (header.mode == plugInModeIndexedColor)
  491.         {
  492.         
  493.         ReadSome (globals, 3 * sizeof (LookUpTable), &gStuff->redLUT);
  494.         
  495.         if (gResult != noErr)
  496.             goto CleanUp;
  497.         
  498.         }
  499.         
  500.     return;
  501.         
  502.     /* The following code does any clean-up work in the event of an error. */
  503.     
  504.     CleanUp:
  505.     
  506.     DisposeImageResources (globals);
  507.         
  508.     }
  509.  
  510. /*****************************************************************************/
  511.  
  512. void DoReadContinue (GPtr globals)
  513.     {
  514.     
  515.     int32 done;
  516.     int32 total;
  517.     int16 plane;
  518.     int16 row;
  519.     
  520.     /* Dispose of the image resource data if it exists. */
  521.     
  522.     DisposeImageResources (globals);
  523.     
  524.     /* Set up the progress variables. */
  525.     
  526.     done = 0;
  527.     total = gStuff->imageSize.v * (long) gStuff->planes;
  528.         
  529.     /* Next, we will allocate the pixel buffer. */
  530.     
  531.     AllocatePixelBuffer (globals);
  532.     
  533.     /* Set up to start returning chunks of data. */
  534.     
  535.     gStuff->theRect.left = 0;
  536.     gStuff->theRect.right = gStuff->imageSize.h;
  537.     gStuff->colBytes = 1;
  538.     gStuff->rowBytes = gRowBytes;
  539.     gStuff->planeBytes = 0;
  540.     gStuff->data = gPixelData;
  541.     
  542.     for (plane = 0; gResult == noErr && plane < gStuff->planes; ++plane)
  543.         {
  544.         
  545.         gStuff->loPlane = gStuff->hiPlane = plane;
  546.         
  547.         for (row = 0; gResult == noErr && row < gStuff->imageSize.v; ++row)
  548.             {
  549.             
  550.             gStuff->theRect.top = row;
  551.             gStuff->theRect.bottom = row + 1;
  552.             
  553.             ReadRow (globals);
  554.             
  555.             if (gResult == noErr)
  556.                 gResult = AdvanceState ();
  557.                 
  558.             UpdateProgress (++done, total);
  559.             
  560.             }
  561.         
  562.         }
  563.         
  564.     gStuff->data = NULL;
  565.     
  566.     DisposePixelBuffer (globals);
  567.     
  568.     }
  569.  
  570. /*****************************************************************************/
  571.  
  572. void DoReadFinish (GPtr globals)
  573.     {
  574.     
  575.     /* Dispose of the image resource data if it exists. */
  576.     
  577.     DisposeImageResources (globals);
  578.     WriteScriptParamsOnRead (globals); // should be different for read/write
  579.     
  580.     }
  581.  
  582. /*****************************************************************************/
  583.  
  584. void DoOptionsPrepare (GPtr globals)
  585.     {
  586.  
  587.     gStuff->maxData = 0;
  588.  
  589.     }
  590.  
  591. /*****************************************************************************/
  592.  
  593. void DoOptionsStart (GPtr globals)
  594.     {
  595.  
  596.     /* Check for the needed services. */
  597.     
  598.     if (!TSC ((Boolean)(!CheckForServices (globals)))) return;
  599.  
  600.     gStuff->data = NULL;
  601.  
  602.     }
  603.  
  604. /*****************************************************************************/
  605.  
  606. void DoOptionsContinue (GPtr globals)
  607.     {
  608.  
  609.     }
  610.  
  611. /*****************************************************************************/
  612.  
  613. void DoOptionsFinish (GPtr globals)
  614.     {
  615.  
  616.     }
  617.  
  618. /*****************************************************************************/
  619.  
  620. void DoEstimatePrepare (GPtr globals)
  621.     {
  622.  
  623.     gStuff->maxData = 0;
  624.  
  625.     }
  626.  
  627. /*****************************************************************************/
  628.  
  629. void DoEstimateStart (GPtr globals)
  630.     {
  631.     
  632.     int32 dataBytes;
  633.     
  634.     /* Check for the needed services. */
  635.     
  636.     if (!TSC ((Boolean)(!CheckForServices (globals)))) return;
  637.  
  638.     dataBytes = sizeof (FileHeader) +
  639.                 gStuff->imageRsrcSize +
  640.                 RowBytes (globals) * gStuff->planes * gStuff->imageSize.v;
  641.                       
  642.     if (gStuff->imageMode == plugInModeIndexedColor)
  643.         dataBytes += 3 * sizeof (LookUpTable);
  644.         
  645.     gStuff->minDataBytes = dataBytes;
  646.     gStuff->maxDataBytes = dataBytes;
  647.     
  648.     gStuff->data = NULL;
  649.  
  650.     }
  651.  
  652. /*****************************************************************************/
  653.  
  654. void DoEstimateContinue (GPtr globals)
  655.     {
  656.  
  657.     }
  658.  
  659. /*****************************************************************************/
  660.  
  661. void DoEstimateFinish (GPtr globals)
  662.     {
  663.  
  664.     }
  665.  
  666. /*****************************************************************************/
  667.  
  668. void DoWritePrepare (GPtr globals)
  669.     {
  670.     
  671.     gStuff->maxData = 0;
  672.     
  673.     }
  674.  
  675. /*****************************************************************************/
  676.  
  677. void DoWriteStart (GPtr globals)
  678.     {
  679.  
  680.     FileHeader header;
  681.     int32 done;
  682.     int32 total;
  683.     int16 plane;
  684.     int16 row;
  685.     
  686.     ReadScriptParamsOnWrite (globals); // read script params here
  687.     
  688.     if (gResult != noErr) return;
  689.         
  690.     /* Check for the needed services. */
  691.     
  692.     if (!TSC ((Boolean)(!CheckForServices (globals)))) return;
  693.  
  694.     /* Write the header. */
  695.     
  696.     gResult = SetFPos (gStuff->dataFork, fsFromStart, 0);
  697.     
  698.     SetIdentifier (header.identifier);
  699.     header.mode = gStuff->imageMode;
  700.     header.rows = gStuff->imageSize.v;
  701.     header.cols = gStuff->imageSize.h;
  702.     header.depth = gStuff->depth;
  703.     header.planes = gStuff->planes;
  704.     
  705.     if (gStuff->imageRsrcData)
  706.         header.resourceLength = gStuff->imageRsrcSize;
  707.     else
  708.         header.resourceLength = 0;
  709.         
  710.     WriteSome (globals, sizeof (FileHeader), &header);
  711.     
  712.     if (gResult != noErr) return;
  713.     
  714.     /* Write the image resources if any. */
  715.     
  716.     if (header.resourceLength > 0)
  717.         {
  718.         
  719.         WriteSome (globals,
  720.                    header.resourceLength,
  721.                    PILockHandle (gStuff->imageRsrcData, FALSE));
  722.         
  723.         PIUnlockHandle (gStuff->imageRsrcData);
  724.         
  725.         if (gResult != noErr) return;
  726.         
  727.         }
  728.         
  729.     /* Write the lookup tables if appropriate. */
  730.     
  731.     if (header.mode == plugInModeIndexedColor)
  732.         {
  733.         
  734.         WriteSome (globals, 3 * sizeof (LookUpTable), &gStuff->redLUT);
  735.         
  736.         if (gResult != noErr) return;
  737.         
  738.         }
  739.         
  740.     /* Set up the progress variables. */
  741.     
  742.     done = 0;
  743.     total = header.rows * (long) header.planes;
  744.         
  745.     /* Next, we will allocate the pixel buffer. */
  746.     
  747.     AllocatePixelBuffer (globals);
  748.         
  749.     /* Set up to start receiving chunks of data. */
  750.     
  751.     gStuff->theRect.left = 0;
  752.     gStuff->theRect.right = header.cols;
  753.     gStuff->colBytes = 1;
  754.     gStuff->rowBytes = gRowBytes;
  755.     gStuff->planeBytes = 0;
  756.     gStuff->data = gPixelData;
  757.     
  758.     for (plane = 0; gResult == noErr && plane < gStuff->planes; ++plane)
  759.         {
  760.         
  761.         gStuff->loPlane = gStuff->hiPlane = plane;
  762.         
  763.         for (row = 0; gResult == noErr && row < gStuff->imageSize.v; ++row)
  764.             {
  765.             
  766.             gStuff->theRect.top = row;
  767.             gStuff->theRect.bottom = row + 1;
  768.             
  769.             if (gResult == noErr)
  770.                 gResult = AdvanceState ();
  771.                 
  772.             WriteRow (globals);
  773.             
  774.             UpdateProgress (++done, total);
  775.             
  776.             }
  777.         
  778.         }
  779.         
  780.     gStuff->data = NULL;
  781.     
  782.     DisposePixelBuffer (globals);
  783.     
  784.     }
  785.  
  786. /*****************************************************************************/
  787.  
  788. void DoWriteContinue (GPtr globals)
  789.     {
  790.  
  791.     }
  792.  
  793. /*****************************************************************************/
  794.  
  795. void DoWriteFinish (GPtr globals)
  796. {
  797.     WriteScriptParamsOnWrite (globals); // should be different for read/write
  798. }
  799.  
  800. /*****************************************************************************/
  801.  
  802. void DoFilterFile (GPtr globals)
  803.     {
  804.     
  805.     FileHeader header;
  806.     
  807.     /* Exit if we have already encountered an error. */
  808.  
  809.     if (gResult != noErr) return;
  810.         
  811.     /* Read the file header. */
  812.        
  813.     if (!TSR (SetFPos (gStuff->dataFork, fsFromStart, 0))) return;
  814.     
  815.     ReadSome (globals, sizeof (FileHeader), &header);
  816.     
  817.     if (gResult != noErr) return;
  818.     
  819.     /* Check the identifier. */
  820.     
  821.     if (!CheckIdentifier (header.identifier))
  822.         {
  823.         gResult = formatCannotRead;
  824.         return;
  825.         }
  826.     
  827.     }
  828.  
  829. /*****************************************************************************/
  830.  
  831.  
  832.  
  833.  
  834.